package com.ruoyi.web.controller.byd;

import com.ruoyi.system.domain.PageData;
import com.ruoyi.system.domain.PartGroup;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.text.PDFTextStripper;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;;

@RestController
@RequestMapping("/files")
public class PdfMaterialThicknessReader {
    // 输出根目录 - 建议使用用户目录或应用目录避免权限问题
    private static final String OUTPUT_ROOT = System.getProperty("user.home") + "/百超六代机图纸拆分结果/";

    /**
     * 处理前端上传的PDF文件
     */
    @PostMapping("/split-pdf")
    public String splitPdf(@RequestParam("file") MultipartFile file) {
        try {
            // 1. 验证文件
            if (file.isEmpty()) {
                return "请上传有效的PDF文件";
            }

            // 2. 解析PDF，提取每页关键信息
            List<PageInfo> pageInfos = parsePdf(file.getInputStream());
            if (pageInfos.isEmpty()) {
                return "PDF内容为空";
            }

            // 3. 按零件名称匹配分组
            List<PartGroup> groups = groupByPartName(pageInfos);

            // 4. 拆分并合并每组PDF（包含目录创建）
            mergeAndSaveGroups(file.getInputStream(), groups);

            return "处理完成，结果保存至：" + OUTPUT_ROOT;
        } catch (EOFException e) {
            return "处理中断：已读取到文档末尾，已保存已处理内容至：" + OUTPUT_ROOT;
        } catch (SecurityException e) {
            return "权限不足：无法访问文件系统，请检查应用权限。详细信息：" + e.getMessage();
        } catch (Exception e) {
            e.printStackTrace();
            return "处理失败：" + e.getMessage();
        }
    }

    /**
     * 解析PDF，提取每页的零件名称和内容
     */
    private List<PageInfo> parsePdf(InputStream inputStream) throws IOException {
        List<PageInfo> pageInfos = new ArrayList<>();
        try (PDDocument document = PDDocument.load(inputStream)) {
            PDFTextStripper stripper = new PDFTextStripper();
            int totalPages = document.getNumberOfPages();

            for (int i = 0; i < totalPages; i++) {
                stripper.setStartPage(i + 1);
                stripper.setEndPage(i + 1);
                String pageText = stripper.getText(document);

                PageInfo info = new PageInfo();
                info.setPageNum(i + 1);
                info.setContent(pageText);

                // 提取零件名称（适配文档中“零件名称:”后的格式）
                Pattern pattern = Pattern.compile("零件名称:\\s*([^\\n]+)");
                Matcher matcher = pattern.matcher(pageText);
                if (matcher.find()) {
                    String partName = matcher.group(1).trim();
                    // 去除多余字符，确保可作为目录名
                    partName = sanitizeFileName(partName);
                    info.setPartName(partName);
                } else {
                    // 对于没有明确零件名称的页面，使用"其他_页码"命名
                    info.setPartName("其他_" + (i + 1));
                }

                pageInfos.add(info);
            }
        }
        return pageInfos;
    }

    /**
     * 清理文件名，移除所有非法字符
     */
    private String sanitizeFileName(String fileName) {
        if (fileName == null || fileName.trim().isEmpty()) {
            return "未命名";
        }
        // 移除Windows和Linux中的非法文件名字符
        String sanitized = fileName.replaceAll("[\\\\/:*?\"<>|]", "_");
        // 限制文件名长度，避免过长路径问题
        return sanitized.length() > 100 ? sanitized.substring(0, 100) : sanitized;
    }

    /**
     * 按零件名称分组
     */
    private List<PartGroup> groupByPartName(List<PageInfo> pageInfos) {
        List<PartGroup> groups = new ArrayList<>();
        if (pageInfos.isEmpty()) {
            return groups;
        }

        // 初始化第一组（以第一页零件名称为基准）
        PartGroup currentGroup = new PartGroup();
        PageInfo firstPage = pageInfos.get(0);
        currentGroup.setPartName(firstPage.getPartName());
        currentGroup.getPageNumbers().add(firstPage.getPageNum());

        // 遍历剩余页面进行分组
        for (int i = 1; i < pageInfos.size(); i++) {
            PageInfo currentPage = pageInfos.get(i);
            String currentPartName = currentPage.getPartName();
            String groupPartName = currentGroup.getPartName();

            // 匹配规则：零件名称相同或包含核心关键词
            boolean isMatch = isPartMatch(currentPartName, groupPartName);

            if (isMatch) {
                currentGroup.getPageNumbers().add(currentPage.getPageNum());
            } else {
                // 不匹配则保存当前组并创建新组
                groups.add(currentGroup);
                currentGroup = new PartGroup();
                currentGroup.setPartName(currentPartName);
                currentGroup.getPageNumbers().add(currentPage.getPageNum());
            }
        }

        // 添加最后一个组
        if (!currentGroup.getPageNumbers().isEmpty()) {
            groups.add(currentGroup);
        }
        return groups;
    }

    /**
     * 判断两个零件名称是否匹配
     */
    private boolean isPartMatch(String currentPartName, String groupPartName) {
        if (currentPartName == null || groupPartName == null) {
            return false;
        }

        // 完全匹配
        if (currentPartName.equals(groupPartName)) {
            return true;
        }

        // 提取核心关键词进行匹配（去除数字后缀）
        String currentCore = currentPartName.replaceAll("(_\\d+)$", "");
        String groupCore = groupPartName.replaceAll("(_\\d+)$", "");

        return currentCore.contains(groupCore) || groupCore.contains(currentCore);
    }

    /**
     * 合并每组页面并保存为新PDF，确保自动创建目录
     */
    private void mergeAndSaveGroups(InputStream inputStream, List<PartGroup> groups) throws IOException {
        // 确保根目录存在，使用Files.createDirectories更可靠
        Path rootPath = Paths.get(OUTPUT_ROOT);
        if (!Files.exists(rootPath)) {
            Files.createDirectories(rootPath);
            // 设置目录可写权限
            setDirectoryWritable(rootPath.toFile());
        }

        try (PDDocument sourceDoc = PDDocument.load(inputStream)) {
            for (PartGroup group : groups) {
                String partName = group.getPartName();
                if (partName == null || partName.trim().isEmpty()) {
                    partName = "未命名组";
                }

                // 创建以零件名称命名的目录
                Path partDirPath = rootPath.resolve(partName);
                File partDir = partDirPath.toFile();
                if (!Files.exists(partDirPath)) {
                    Files.createDirectories(partDirPath);
                    // 设置目录可写权限
                    setDirectoryWritable(partDir);
                }

                // 创建新文档存放当前组页面
                try (PDDocument targetDoc = new PDDocument()) {
                    for (int pageNum : group.getPageNumbers()) {
                        // PDFBox页码从0开始，需转换
                        if (pageNum - 1 < sourceDoc.getNumberOfPages()) {
                            PDPage page = sourceDoc.getPage(pageNum - 1);
                            targetDoc.addPage(page);
                        }
                    }

                    // 保存文件（使用零件名称作为文件名）
                    String fileName = sanitizeFileName(partName) + ".pdf";
                    Path outputFilePath = partDirPath.resolve(fileName);

                    // 检查文件是否已存在，若存在则删除或重命名
                    if (Files.exists(outputFilePath)) {
                        Files.delete(outputFilePath);
                    }

                    targetDoc.save(outputFilePath.toFile());
                    // 设置文件可读写权限
                    setFileReadableWritable(outputFilePath.toFile());
                }
            }
        }
    }

    /**
     * 设置目录为可写
     */
    private void setDirectoryWritable(File dir) {
        if (dir.exists() && !dir.canWrite()) {
            dir.setWritable(true, false);
            dir.setReadable(true, false);
            dir.setExecutable(true, false);
        }
    }

    /**
     * 设置文件为可读写
     */
    private void setFileReadableWritable(File file) {
        if (file.exists()) {
            file.setReadable(true, false);
            file.setWritable(true, false);
        }
    }

    /**
     * 辅助类：存储单页PDF信息
     */
    private static class PageInfo {
        private int pageNum;
        private String partName;
        private String content;

        // getter和setter
        public int getPageNum() { return pageNum; }
        public void setPageNum(int pageNum) { this.pageNum = pageNum; }
        public String getPartName() { return partName; }
        public void setPartName(String partName) { this.partName = partName; }
        public String getContent() { return content; }
        public void setContent(String content) { this.content = content; }
    }

    /**
     * 辅助类：存储每组零件的页面集合
     */
    private static class PartGroup {
        private String partName;
        private List<Integer> pageNumbers = new ArrayList<>();

        // getter和setter
        public String getPartName() { return partName; }
        public void setPartName(String partName) { this.partName = partName; }
        public List<Integer> getPageNumbers() { return pageNumbers; }
        public void setPageNumbers(List<Integer> pageNumbers) { this.pageNumbers = pageNumbers; }
    }
}
